package com.jt.config;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * 定时器
 */

@Configuration
@EnableScheduling
public abstract class TimingConfig implements SchedulingConfigurer {

    private String schedulerName;   

    private Boolean isSwitch;

    private String cron;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        /*设定线程池*/
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(2));
        if (getSwitch()) {
            taskRegistrar.addTriggerTask(
                    // 执行定时任务
                    () -> {
                        try {
                            processTask();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    },
                    // 设置触发器
                    triggerContext -> {
                        // 初始化定时任务周期
                        if (StringUtils.isEmpty(cron)) {
                            cron = getCron();
                        }
                        CronTrigger trigger = new CronTrigger(cron);
                        return trigger.nextExecutionTime(triggerContext);
                    }
            );


        }
    }

    /**
     * 自定义线程池，用于执行定时任务
     */
    @Bean
    public Executor taskScheduler() {
        // 设置线程名称
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("task-pool-%d").build();
        // 创建线程池
        return Executors.newScheduledThreadPool(10, namedThreadFactory);
    }

    protected abstract Boolean getSwitch();


    protected abstract void processTask() throws IOException;


    protected abstract String getCron();

}
